/*
   FieldVis - A Tool for Visualizing Astrophysical Magnetohydrodynamic Flow
   
   Copyright (C) 2006 - 2008     FieldVis Development Team
  
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.
  
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
  
   You should have received a copy of the GNU General Public License along
   with this program; if not, write to the Free Software Foundation, Inc.,
   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

   File     : ConfigFile.h
   Author   : Blayne Field
   
   Purpose  : Definition header file for the ConfigFile class.
              This class is for managing a single config file.
              The goal is to recalculate as little as possible.
*/

#ifndef CONFIG_FILE_H
#define CONFIG_FILE_H

#include <iostream>
#include <fstream>
#include <map>
#include <sstream>
#include <string>
#include <time.h>
#include <unistd.h>
#include <pthread.h>

#include <GL/gl.h>

#include "Point.h"
#include "Vector3D.h"
#include "Field.h"
#include "Streamtube.h"
#include "PtrDeleteT.h"

// these 2 functions from ResourceFile.cpp
extern std::string GetFullPathToFile(const std::string &filename);
extern std::string GetFullPathToFileCheckRC(const std::string &filename,
                                            const std::string &cwd,
                                            const std::vector<std::string> &rc);

class ConfigFile
{
public:
   ConfigFile(const std::string &fileName, const std::vector<std::string> &rc);
   ~ConfigFile();

   void Reload();
   void ReloadNameValuePairs();
   void UpdatePaths();

   void AddStreamlineSeed(Point);
   void RemoveStreamlineSeed(int index);
   int MoveStreamlineSeed(int, Point);
   Point GetStreamlinePoint(int tubeIndex, int pointIndex);
   void SetBoxSize(float *x, float *y, float *z);
   void WriteSeedsToFile();

   void DrawStreamtubes(GLenum mode);

   float GetScaleFactor() const                 { return(vfield->GetScaleFactor()); }
   ColorMap * GetColorMap() const               { return(colorMap); }
   int GetStreamtubeLength(int tubeIndex) const { return(vTube[tubeIndex]->GetPointCount()); }

private:

   void SetUpExternalFields();
   float GetFloatFromAttribute(std::string attr)   { return((float) atof(pairs[attr].c_str())); }
   int GetIntFromAttribute(std::string attr)       { return((int) atoi(pairs[attr].c_str())); }
   Streamtube *CreateStreamtube(const int ID);

   static void *CreateStreamtubeThread(void *arg);

   std::string fileName;
   std::vector<std::string> resources;
   std::map <std::string, std::string> pairs;

   bool streamlinesMoved;

   VectorField *vfield;
   ColorMap    *colorMap;
   Texture     *tex;
   ScalarField *twistField;
   ScalarField *radiusField;

   std::vector<Streamtube*> vTube;
   std::vector<Point> seedPoints;
};

struct ConfigThreadInfo
{
   int ID;
   ConfigFile *config;
   Streamtube *tube;
};

class ConfigFileManager
{
public:

   ConfigFileManager()     { }

   ~ConfigFileManager()
      { for_each( cfm.begin(), cfm.end(), PtrDelete<ConfigFile>() );  cfm.clear(); }

   void Manage(ConfigFile *elem)    { cfm.push_back(elem); }

   unsigned int Count()             { return(cfm.size()); }

   ConfigFile* &operator[](unsigned int i)   { return(cfm.at(i)); }

private:

   std::vector<ConfigFile*> cfm;
};

#endif

